<template>
    <div class="stockDialog">
        <div v-if="showDialog" :class="{ 'full-screen': isFullScreen }">
            <yh-dialog
                :visible.sync="stockDialog"
                :modal="false"
                :fullscreen="isFullScreen"
                :close-on-click-modal="false"
                :close-on-press-escape="false"
                :before-close="close"
                :drag="!isFullScreen"
                top="0"
                :key="key"
                :show-close="false"
            >
                <template slot="title">
                    <div style="margin:auto; color: black">{{ '成分股信息-' + title }}</div>
                    <div class="flex1">
                        <div :class="!isFullScreen ? 'el-icon-full-screen' : 'el-icon-minus'" class="btn1" @click="onFullScreen"></div>
                        <div class="btn2" @click="close"></div>
                    </div>
                </template>
                <div class="table-content">
                    <div style="height: calc(100vh - 135px);">
                        <vxe-table
                            :key="tableKey"
                            :header-cell-style="{ backgroundColor: '#e8f3ff', padding: '4px 0' }"
                            :footer-cell-style="{ backgroundColor: '#e8f3ff', padding: '4px 0' }"
                            :data="tableData"
                            border
                            v-loading="tableLoading"
                            element-loading-text="加载中"
                            size="mini"
                            height="100%"
                            ref="xTable"
                            style="cursor: pointer"
                            highlight-current-row
                            highlight-hover-row
                            stripe
                            auto-resize
                            resizable
                            @sort-change="handleSortChange"
                            @filter-change="handleFilterChange"
                            :sort-config="{ sortMethod: customSortMethod }"
                            show-header-overflow
                            show-footer
                            show-footer-overflow
                            :footer-method="footerMethod"
                        >
                            <template v-for="(item, index) in columns">
                                <vxe-column
                                    show-overflow
                                    :key="index + 'name'"
                                    :title="item.title"
                                    :field="item.field"
                                    :min-width="item.minWidth"
                                    :fixed="item.fixed"
                                    :align="item.align"
                                    :filters="item.filters"
                                    :filter-method="item.filterMethod"
                                    sortable
                                >
                                    <template #filter="{ $panel, column }" v-if="item.filterType === 'search'">
                                        <div>
                                            <el-input
                                                ref="searchInput"
                                                class="my-input"
                                                type="type"
                                                v-for="(option, index) in column.filters"
                                                :key="index"
                                                v-model="option.data"
                                                @input="$panel.changeOption($event, !!option.data, option)"
                                            />
                                        </div>
                                    </template>
                                    <template slot-scope="scope">
                                        <span v-if="item.render && typeof item.render === 'function'">
                                            <span v-if="item.field == 'purchaseBalance'">{{
                                                orderForm.orderDirection == 'P'
                                                    ? item.render(scope.row['purchaseBalance'], scope.row)
                                                    : item.render(scope.row['redeemBalance'], scope.row)
                                            }}</span>
                                            <span
                                                v-else-if="['positionAmount', 'availableAmount'].includes(item.field) && scope.row['cashType'] == '2'"
                                                >{{ 'N/A' }}</span
                                            >
                                            <span v-else>{{ item.render(scope.row[item.field], scope.row) }}</span>
                                        </span>
                                        <span v-else>{{ scope.row[item.field] || '--' }}</span>
                                    </template>
                                </vxe-column>
                            </template>
                        </vxe-table>
                    </div>
                    <RiskPagination :paging="paging" @page-change="handlePageChange"></RiskPagination>
                </div>
            </yh-dialog>
        </div>
        <div v-else class="table-content" style="height: 100%">
            <div style="height: calc(100% - 45px);">
                <vxe-table
                    :key="tableKey"
                    :header-cell-style="{ backgroundColor: '#e8f3ff', padding: '4px 0' }"
                    :footer-cell-style="{ backgroundColor: '#e8f3ff', padding: '4px 0' }"
                    :data="tableData"
                    border
                    v-loading="tableLoading"
                    element-loading-text="加载中"
                    size="mini"
                    height="100%"
                    ref="xTable"
                    style="cursor: pointer"
                    highlight-current-row
                    highlight-hover-row
                    stripe
                    auto-resize
                    resizable
                    @sort-change="handleSortChange"
                    @filter-change="handleFilterChange"
                    :sort-config="{ sortMethod: customSortMethod }"
                    show-header-overflow
                    show-footer
                    show-footer-overflow
                    :footer-method="footerMethod"
                >
                    <template v-for="(item, index) in columns">
                        <vxe-column
                            show-overflow
                            :key="index + 'name'"
                            :title="item.title"
                            :field="item.field"
                            :min-width="item.minWidth"
                            :fixed="item.fixed"
                            :align="item.align"
                            :filters="item.filters"
                            :filter-method="item.filterMethod"
                            sortable
                        >
                            <template #filter="{ $panel, column }" v-if="item.filterType === 'search'">
                                <div>
                                    <el-input
                                        ref="searchInput"
                                        class="my-input"
                                        type="type"
                                        v-for="(option, index) in column.filters"
                                        :key="index"
                                        v-model="option.data"
                                        @input="$panel.changeOption($event, !!option.data, option)"
                                    />
                                </div>
                            </template>
                            <template slot-scope="scope">
                                <span v-if="item.render && typeof item.render === 'function'">
                                    <span v-if="item.field == 'purchaseBalance'">{{
                                        orderForm.orderDirection == 'P'
                                            ? item.render(scope.row['purchaseBalance'], scope.row)
                                            : item.render(scope.row['redeemBalance'], scope.row)
                                    }}</span>
                                    <span v-else-if="['positionAmount', 'availableAmount'].includes(item.field) && scope.row['cashType'] == '2'">{{
                                        'N/A'
                                    }}</span>
                                    <span v-else>{{ item.render(scope.row[item.field], scope.row) }}</span>
                                </span>
                                <span v-else>{{ scope.row[item.field] || '--' }}</span>
                            </template>
                        </vxe-column>
                    </template>
                </vxe-table>
            </div>
            <RiskPagination :paging="paging" @page-change="handlePageChange"></RiskPagination>
        </div>
    </div>
</template>

<script lang="ts">
import RiskPagination from '@/common/components/risk-pagination.vue';
import RiskTable from '@/common/components/risk-table.vue';
import { dateFormat, getCurrentPageData, numberFormat, sortBy, timeFormat } from '@/utils/tools';
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import * as moment from 'moment';
import ETFColumnUtil from '../utils/etf-column-util';
import { getEtfStockList } from '../api/etf';
import { VueObject } from 'vue/types/index';

export interface pages {
    total?: number;
    pageSize?: number;
    currentPage?: number;
}
@Component({
    name: 'ConstituentStockDialog',
    components: { RiskTable, RiskPagination },
})
/**
 * 成分股信息弹框
 */
export default class ConstituentStockDialog extends Vue {
    @Prop() stockDialog: boolean;
    @Prop() orderDirection: string;
    @Prop() orderForm: any;
    @Prop() etfBasicInfo: any;
    @Prop() showDialog: boolean;

    ETFColumnUtil = new ETFColumnUtil();
    key: number = 0;
    tableKey: number = 0;
    iconDom: any = null;
    checkFiltersIndex: any[] = [1, 3];
    columns: any[] = [];
    isFullScreen: boolean = true;
    stockTableData: any[] = []; // 表格数据
    // 汇总行
    summary: any = {
        marketValue: 0,
        redeemBalance: 0,
        purchaseBalance: 0,
    };
    tableLoading: boolean = false;
    paging: pages = {
        total: 0,
        pageSize: 10,
        currentPage: 1,
    };
    title: string = ''; // 标题
    footerData: any[] = []; // 表尾展示合计数据
    resultFilterList: any[] = [];
    resultSortList: any[] = [];

    // 筛选后的数据
    filterTable: any[] = [];
    tableData: any[] = [];
    sort: any = {}; // 排序字段

    @Watch('isFullScreen', { immediate: true, deep: true })
    onWatchIsFullScreen() {
        this.key++;
    }

    @Watch('etfBasicInfo', { immediate: true, deep: true })
    onWatchStockCode() {
        this.getStockList();
    }

    /**
     * 根据委托方向不同动态显示成分股信息表格字段
     */
    @Watch('orderForm.orderDirection', { immediate: true, deep: true })
    getStockColumns(value) {
        this.$nextTick(() => {
            let tableColumns = [].concat(this.ETFColumnUtil.constituentStockColumns);
            if (this.orderForm.orderDirection == 'P' || !this.orderForm.orderDirection) {
                tableColumns.splice(11, 3);
                this.title = '基金申购';
            } else {
                tableColumns.splice(8, 3);
                this.title = '基金赎回';
            }
            this.columns = tableColumns;
            let refObj: any = this.$refs['xTable'];

            this.changeTable();
            if (refObj) {
                refObj.refreshColumn();
            }
        });
    }

    // 获取成分股信息
    getStockList() {
        let etfStockQueryForm = {
            estimatecash: this.etfBasicInfo?.estimatecash || 0,
            execType: this.etfBasicInfo?.execType || '',
            fundCode: this.orderForm.fundCode || '',
            instructionAmount: Number(this.orderForm.orderAmount) || 0,
            instructionBalance: Number(this.orderForm.instructionBalance) || 0,
            orderDirection: this.orderForm.orderDirection || '',
            stockCode: this.etfBasicInfo?.stockCode || '',
            stockTargetType: this.orderForm.targetType == '1' ? '2' : '1', // 证券目标类型: 1-按金额 2-按数量 C_STOCK_TARGET_TYPE 【要注意C_TARGET_TYPE：2-按金额 1-按数量】
        };
        if (this.etfBasicInfo) {
            getEtfStockList(etfStockQueryForm).then(res => {
                this.stockTableData = res;
                this.paging.total = res?.length;
                if (res?.length) {
                    res.forEach(ele => {
                        this.summary.marketValue += ele.marketValue; // 市值汇总
                        this.summary.redeemBalance += ele.redeemBalance; // 赎回替代金额汇总
                        this.summary.purchaseBalance += ele.purchaseBalance; // 申购金额替代汇总
                    });
                }
                this.handlePageChange(1);
            });
        } else {
            this.stockTableData = [];
            this.tableData = [];
            this.paging.total = 0;
            this.summary = {
                marketValue: 0,
                redeemBalance: 0,
                purchaseBalance: 0,
            };
        }
    }

    // 试算结果表排序
    handleSortChange({ column, property, order, sortBy, sortList, $event }) {
        if (order) {
            let type = order == 'asc' ? '1' : order == 'desc' ? '-1' : '';
            this.sort = { property, type };
        } else {
            this.sort = {};
        }
        this.resultSortList = sortList;
        // this.paging.currentPage = 1;
        this.handlePageChange(1);
    }

    // 试算结果表筛选
    handleFilterChange({ column, property, values, datas, filterList, $event }) {
        this.resultFilterList = filterList;
        this.filterTable = this.stockTableData;
        if (this.resultFilterList.length) {
            this.resultFilterList.forEach(ele => {
                if (['marketCode', 'cashType'].includes(ele.property)) {
                    this.filterTable = this.filterTable.filter(row => {
                        return ele.values.includes(row[ele.property]);
                    });
                } else {
                    this.filterTable = this.filterTable.filter(row => {
                        return row[ele.property].includes(ele.datas);
                    });
                }
            });
        }
        this.handlePageChange(1);
    }

    // 分页;
    handlePageChange(curPage: number): void {
        if (curPage) {
            this.paging.currentPage = curPage;
        }
        let data = [];
        // 带筛选条件分页
        if (this.resultFilterList.length) {
            data = JSON.parse(JSON.stringify(this.filterTable));
            this.paging.total = this.filterTable.length ? this.filterTable.length : 0;
            // 排序
            if (this.sort?.type) {
                data = data.slice().sort(this.compare(this.sort.property, this.sort.type));
            } else {
                // eslint-disable-next-line no-self-assign
                data = data;
            }
            this.tableData = getCurrentPageData(data, this.paging.currentPage, this.paging.pageSize);
        } else {
            data = JSON.parse(JSON.stringify(this.stockTableData));
            // 不带筛选条件分页
            this.paging.total = this.stockTableData.length ? this.stockTableData.length : 0;
            // 排序
            if (this.sort?.type) {
                data = data.slice().sort(this.compare(this.sort.property, this.sort.type));
            } else {
                // eslint-disable-next-line no-self-assign
                data = data;
            }
            this.tableData = getCurrentPageData(data, this.paging.currentPage, this.paging.pageSize);
        }
        // (this.$refs.resultTable as any).reloadData(this.tableData);
    }

    /**
     * 比较函数
     * @param  {string} prop 数据里面要排序的key
     * @param  {number} type 1:asc  -1:desc
     * @return {number}
     */
    private compare(prop, type) {
        if (['marketCode', 'stockCode', 'stockName', 'cashType'].includes(prop)) {
            // 排string
            return function(obj1: any, obj2) {
                if (type == '1') {
                    return obj1[prop].localeCompare(obj2[prop], 'zh-CN', { numeric: true });
                } else if (type == '-1') {
                    return obj2[prop].localeCompare(obj1[prop], 'zh-CN', { numeric: true });
                }
            };
        } else {
            // 排number
            return function(a, b) {
                if (type == '-1') {
                    return b[prop] - a[prop];
                } else {
                    return a[prop] - b[prop];
                }
            };
        }
    }

    /**
     * 获取表尾数据
     */
    footerMethod() {
        // 返回一个二维数组的表尾合计
        let arr = [];
        let summaryColumns = [];
        this.footerData = [];
        if (this.orderForm.orderDirection == 'P') {
            summaryColumns = ['marketValue', 'purchaseBalance'];
        } else {
            summaryColumns = ['marketValue', 'redeemBalance'];
        }
        if (this.stockTableData.length) {
            let count = 0;
            for (let item of this.columns) {
                const field = item['field'];
                if (summaryColumns.includes(field) && this.summary[field] !== undefined) {
                    arr[count++] = numberFormat(this.summary[field], 2);
                } else {
                    arr[count++] = '--';
                }
            }
            arr[0] = '总计';
            // 证券数量总计
            arr[2] = this.stockTableData.length + '只';
            this.footerData = [arr];
        }
        return this.footerData;
    }

    changeTable() {
        this.$nextTick(() => {
            // 需要改icon的列
            const magnifyingGlass = this.columns.filter(i => i.filterType === 'search').map(i => i.field);
            // 所有列dom
            const cols = (this.$refs['xTable'] as VueObject).getColumns();
            // 找到需要改icon的列domids
            let magnifyingGlassDomIds = [];
            cols.forEach(element => {
                if (magnifyingGlass.includes(element.property)) {
                    magnifyingGlassDomIds.push(element.id);
                }
            });
            magnifyingGlassDomIds.forEach(colid => {
                (this.$refs['xTable'] as VueObject).$el.querySelector(`th[data-colid=${colid}] .vxe-icon--funnel`).className =
                    'vxe-filter--btn el-icon-search';
            });
        });
    }

    // 表格列筛选数据
    filterHandler({ option, row, column }) {
        const property = column['property'];
        return row[property].includes(option.data);
    }

    filterMarketCode({ value, row, column }) {
        return row.MarketCode == value;
    }

    filterCashTypeMethod({ value, row, column }) {
        return row.cashType == value;
    }

    getCellStyle({ column }) {
        let value = 'text-align:right';
        let obj = this.columns.find(item => item.val == column.property);
        if (obj) {
            value = 'text-align: ' + (obj.align || 'right');
        }
        return value;
    }

    // 关闭对话框
    close() {
        this.$emit('closeStockDialog');
    }

    // 全屏点击
    onFullScreen() {
        this.isFullScreen = !this.isFullScreen;
    }
}
</script>

<style lang="scss" scoped>
@import '@/pages/report/styles/common';
.stockDialog {
    height: 100%;
}
.title-icon {
    width: 20px;
    height: 20px;
    display: inline-block;
    border: 4px solid #2288ff;
    border-radius: 50%;
    margin-right: 4px;
}
.title-text {
    display: inline-block;
    font-weight: 900;
}
.my-input {
    margin: 4px;
    width: 96%;
}
/deep/ .el-dialog {
    .el-dialog__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        background-color: #fff;
        border-bottom: 1px solid #ccc;
        padding: 4px !important;
        .el-dialog__title {
            font-size: 16px;
            color: #333333;
        }
        .el-dialog__headerbtn .el-dialog__close {
            font-size: 24px;
            color: #515151;
        }
    }
    .el-dialog__body {
        max-height: 100%;
    }
}
.full-screen /deep/ .el-dialog {
    left: 0px !important;
    top: 0px !important;
}

.flex1 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .btn1 {
        font-size: 24px;
        margin: 0 10px;
        cursor: pointer;
    }
    .btn2 {
        font-size: 24px;
        cursor: pointer;
        width: 35px;
        height: 28px;
        background-image: url('~@/pages/system-preserve/images/entry-monitor/close.png');
        background-size: 100% 100%;
        background-repeat: no-repeat;
    }
}
/deep/ .el-dialog__wrapper {
    overflow: hidden;
}
.top-content /deep/ .vxe-table .vxe-table--body-wrapper.body--wrapper {
    // height: fit-content;
    // max-height: calc(47vh - 115px);
    height: calc(47vh - 135px);
}
.content /deep/ .vxe-table .vxe-table--body-wrapper.body--wrapper {
    // height: fit-content;
    // max-height: calc(94vh - 130px);
    height: calc(94vh - 130px);
}

.table /deep/ .vxe-cell .vxe-cell--title {
    font-size: 14px;
}

/deep/.vxe-table {
    .vxe-table--filter-wrapper {
        .vxe-table--filter-body {
            height: 40%;
            max-height: 100px;
            padding-bottom: 0;
        }
    }
}
</style>
